/*
 * Copyright 2009 Brook Smith brook.smith@paradise.net.nz.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.javagenerate.generator;

public class AccessorDefinition {

	public class StandardGetter extends MethodDefinition {
		public StandardGetter(AccessorDefinition beanDefinition) {
			super(beanDefinition.getType(), beanDefinition.getAccessorName());
			StringBuffer sb = new StringBuffer();
			sb.append("\treturn ").append(beanDefinition.getName()).append(";");
			setContent(sb.toString());
		}
	}

	public class StandardSetter extends MethodDefinition {
		public StandardSetter(AccessorDefinition beanDefinition) {
			super(beanDefinition.getType(), beanDefinition.getMutatorName());
			setReturnType("void");
			StringBuffer sb = new StringBuffer();
			sb.append("\tthis.").append(beanDefinition.getName()).append(" = ").append(beanDefinition.getName()).append(";");
			setContent(sb.toString());
			getParameters().add(new Parameter(beanDefinition.getName(), beanDefinition.getType()));
		}
	}

	public static String methodCaseName(String variable) {
		return variable.substring(0, 1).toUpperCase() + variable.substring(1);
	}

	public static String variableCaseName(String variable) {
		return variable.substring(0, 1).toLowerCase() + variable.substring(1);
	}

	private String name;
	private String type;
	private String packageName = null;
	private boolean hasGetter = true;

	private boolean hasSetter = true;

	private String annotation = null;

	public AccessorDefinition(boolean getter, boolean setter, String name, String type) {
		setName(name);
		setType(type);
		setHasGetter(getter);
		setHasSetter(setter);
	}

	public AccessorDefinition(String name, String type) {
		setName(name);
		setType(type);
	}

	public void addBean(BaseGenerator generator) {
		if (generator.isClass()) {
			generator.addLocalVariable(new VariableDefinition("private", getType(), getName(), null, getAnnotation()));
		}

		if (packageName != null) {
			generator.getImports().add(packageName);
		}
		if (isHasGetter()) {
			MethodDefinition methodDefinition = new StandardGetter(this);
			methodDefinition.setInterface(!generator.isClass());
			generator.addBeanMethods(this);
			generator.addMethod(methodDefinition);
		}
		if (isHasSetter()) {
			MethodDefinition methodDefinition = new StandardSetter(this);
			methodDefinition.setInterface(!generator.isClass());
			generator.addMethod(methodDefinition);
		}
	}

	private String extractPackageName(String variable) {
		int lastDot = variable.lastIndexOf('.');
		if (lastDot < 0) {
			return null;
		}
		return variable;
	}

	public String getAccessorName() {
		String prefix = "get";
		if (type.equals("boolean")) {
			prefix = "is";
		}
		return prefix + methodCaseName(getName());
	}

	public String getAnnotation() {
		return annotation;
	}

	public String getMutatorName() {
		return "set" + methodCaseName(getName());
	}

	public String getName() {
		return name;
	}

	public String getType() {
		return type;
	}

	public boolean isHasGetter() {
		return hasGetter;
	}

	public boolean isHasSetter() {
		return hasSetter;
	}

	public void setAnnotation(String annotation) {
		this.annotation = annotation;
	}

	public void setHasGetter(boolean hasGetter) {
		this.hasGetter = hasGetter;
	}

	public void setHasSetter(boolean hasSetter) {
		this.hasSetter = hasSetter;
	}

	public void setName(String name) {
		this.name = variableCaseName(name);
	}

	public void setType(String type) {
		this.packageName = extractPackageName(type);
		int lastDot = type.lastIndexOf('.');
		this.type = type;
		if (lastDot >= 0) {
			this.type = type.substring(lastDot + 1);
		}
	}

}
